﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Runtime.InteropServices;
using RestAndPlay.Core.Model;
using RestAndPlay.Core.Repository;
using RestAndPlay.Player.Player;
using System.Diagnostics;

namespace RestAndPlay.Player
{

    [ServiceContract]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class RestPlayerService
    {

        [WebGet(UriTemplate = "playlist?username={username}",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
        List<PlaylistSong> GetPlaylist(String username)
        {
            Trace.TraceInformation(string.Format("GetPlaylist(username = {0})", username));
            try
            {

                return RepositoryFactory.GetPlaylistRepository()
                    .GetPlaylist();

            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }

        [WebGet(UriTemplate = "playlist/queue?username={username}&song={path}",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
        void Queue(String username, String path)
        {
            Trace.TraceInformation(string.Format("Queue(username = {0}, path = {1})", username, path));
            try
            {

                var user = new User
                {
                    Username = username
                };

                var song = new Song
                {
                    Path = path
                };

                var playlistSong = new PlaylistSong
                {
                    Date = DateTimeOffset.Now,
                    Owner = user,
                    Song = song
                };

                RepositoryFactory.GetActionsRepository()
                    .AddAction(new PlayerAction { Type = ActionType.Queue, User = user, PlaylistSong = playlistSong });

                RepositoryFactory.GetPlaylistRepository()
                    .Queue(playlistSong);

            }
            catch(Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }

        [WebGet(UriTemplate = "playlist/dequeue?username={username}&song={path}",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
        void Dequeue(String username, String path)
        {
            Trace.TraceInformation(string.Format("Dequeue(username = {0}, path = {1})", username, path));
            try
            {

                var user = new User
                {
                    Username = username
                };

                var song = new Song
                {
                    Path = path
                };

                var playlistSong = new PlaylistSong
                {
                    Date = DateTimeOffset.Now,
                    Owner = user,
                    Song = song
                };

                RepositoryFactory.GetActionsRepository()
                    .AddAction(new PlayerAction { Type = ActionType.Dequeue, User = user });

                RepositoryFactory.GetPlaylistRepository()
                    .Dequeue(playlistSong);
                        
            }
            catch(Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }

        [WebGet(UriTemplate = "player?username={username}",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
        PlaylistSong GetCurrentSong(String username)
        {
            Trace.TraceInformation(string.Format("GetCurrentSong(username = {0})", username));
            try
            {

                var user = new User
                {
                    Username = username
                };

                var currentSong = RepositoryFactory.GetPlaylistRepository()
                                    .GetPlaylist()
                                    .FirstOrDefault(p => p.Status == PlaylistSongStatus.Playing);

                if (currentSong == null)
                {
                    currentSong = RepositoryFactory.GetPlaylistRepository()
                                    .GetPlaylist()
                                    .FirstOrDefault();

                    RepositoryFactory.GetPlaylistRepository()
                        .UpdateStatus(currentSong, PlaylistSongStatus.Playing);
                }

                return currentSong;

            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }

        [WebGet(UriTemplate = "player/play?username={username}",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
        void Play(String username)
        {
            Trace.TraceInformation(string.Format("Play(username = {0})", username));
            try
            {

                var user = new User
                {
                    Username = username
                };

                RepositoryFactory.GetActionsRepository()
                    .AddAction(new PlayerAction { Type = ActionType.Play, User = user });

                var currentSong = this.GetCurrentSong(username);

                MediaPlayer.Instance.Play(currentSong.Song.Path);

            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }

        [WebGet(UriTemplate = "player/pause?username={username}",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
        void Pause(String username)
        {
            Trace.TraceInformation(string.Format("Pause(username = {0})", username));
            try
            {

                var user = new User
                {
                    Username = username
                };

                RepositoryFactory.GetActionsRepository()
                    .AddAction(new PlayerAction { Type = ActionType.Pause, User = user });
            
                MediaPlayer.Instance.Pause();

            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }

        [WebGet(UriTemplate = "player/stop?username={username}",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
        void Stop(String username)
        {
            Trace.TraceInformation(string.Format("Stop(username = {0})", username));
            try
            {

                var user = new User
                {
                    Username = username
                };

                RepositoryFactory.GetActionsRepository()
                    .AddAction(new PlayerAction { Type = ActionType.Stop, User = user });

                MediaPlayer.Instance.Pause();

            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }

        [WebGet(UriTemplate = "volume?username={username}",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
        double GetVolumen(String username)
        {
            Trace.TraceInformation(string.Format("GetVolumen(username = {0})", username));
            try
            {

                return MediaPlayer.Instance.GetVolume();
                            
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }

        [WebGet(UriTemplate = "volume/up?username={username}",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
        void VolumeUp(String username)
        {
            Trace.TraceInformation(string.Format("VolumeUp(username = {0})", username));
            try
            {

                var user = new User
                {
                    Username = username
                };

                RepositoryFactory.GetActionsRepository()
                    .AddAction(new PlayerAction { Type = ActionType.VolumeUp, User = user });

            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }

        [WebGet(UriTemplate = "volume/down?username={username}",
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
        void VolumeDown(String username)
        {
            Trace.TraceInformation(string.Format("VolumeDown(username = {0})", username));
            try
            {

                var user = new User
                {
                    Username = username
                };

                RepositoryFactory.GetActionsRepository()
                    .AddAction(new PlayerAction { Type = ActionType.VolumeDown, User = user });

            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
        }

    }

}
